﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reflection;

namespace CG.Common.Extensions
{
	public static class NotificationExtensions
	{
		public static void Notify(this PropertyChangedEventHandler eventHandler, Expression<Func<object>> expression)
		{
			if (null == eventHandler || expression == null)
				return;

			var lambda = expression as LambdaExpression;
			MemberExpression memberExpression;
			if (lambda.Body is UnaryExpression)
			{
				var unaryExpression = lambda.Body as UnaryExpression;
				memberExpression = unaryExpression.Operand as MemberExpression;
			}
			else
			{
				memberExpression = lambda.Body as MemberExpression;
			}
			var constantExpression = memberExpression.Expression as ConstantExpression;
			var propertyInfo = memberExpression.Member as PropertyInfo;

			foreach (var del in eventHandler.GetInvocationList())
			{
				del.DynamicInvoke(new object[] { constantExpression.Value, new PropertyChangedEventArgs(propertyInfo.Name) });
			}
		}

		public static void NotifyAll(this PropertyChangedEventHandler eventHandler, INotifyPropertyChanged obj)
		{
			if (null == eventHandler || obj == null)
				return;

			foreach (PropertyDescriptor desc in TypeDescriptor.GetProperties(obj))
			{
				foreach (var del in eventHandler.GetInvocationList())
				{
					del.DynamicInvoke(new object[] { obj, new PropertyChangedEventArgs(desc.Name) });
				}
			}
		}
	}
}
